home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 223_01 / cc31.c < prev    next >
Text File  |  1980-01-01  |  8KB  |  296 lines

  1. /*
  2. ** lval[0] - symbol table address, else 0 for constant
  3. ** lval[1] - type of indirect obj to fetch, else 0 for static
  4. ** lval[2] - type of pointer or array, else 0 for all other
  5. ** lval[3] - true if constant expression
  6. ** lval[4] - value of constant expression (+ auxiliary uses)
  7. ** lval[5] - true if secondary register altered
  8. ** lval[6] - function address of highest/last binary operator
  9. ** lval[7] - stage address of "oper 0" code, else 0
  10. */
  11.  
  12. /*
  13. ** skim over terms adjoining || and && operators
  14. */
  15. skim(opstr, testfunc, dropval, endval, hier, lval)
  16.   char *opstr;
  17.   int (*testfunc)(), dropval, endval, (*hier)(), lval[]; { /*13*/
  18.   int k, hits, droplab, endlab;
  19.   hits=0;
  20.   while(1) {
  21.     k=plnge1(hier, lval);
  22.     if(nextop(opstr)) {
  23.       bump(opsize);
  24.       if(hits==0) {
  25.         hits=1;
  26.         droplab=getlabel();
  27.         }
  28.       dropout(k, testfunc, droplab, lval);
  29.       }
  30.     else if(hits) {
  31.       dropout(k, testfunc, droplab, lval);
  32.       const(endval);
  33.       jump(endlab=getlabel());
  34.       postlabel(droplab);
  35.       const(dropval);
  36.       postlabel(endlab);
  37.       lval[1]=lval[2]=lval[3]=lval[4]=lval[7]=0;  /*50*/
  38.       return 0;
  39.       }
  40.     else return k;
  41.     }
  42.   }
  43.  
  44. /*
  45. ** test for early dropout from || or && evaluations
  46. */
  47. dropout(k, testfunc, exit1, lval)
  48.   int k, (*testfunc)(), exit1, lval[]; {                /*13*/
  49.   if(k) rvalue(lval);
  50.   else if(lval[3]) const(lval[4]);
  51.   (*testfunc)(exit1); /* jumps on false */              /*13*/
  52.   }
  53.  
  54. /*
  55. ** plunge to a lower level
  56. */
  57. plnge(opstr, opoff, hier, lval)
  58.   char *opstr;
  59.   int opoff, (*hier)(), lval[]; {                       /*13*/
  60.   int k, lval2[8];
  61.   k=plnge1(hier, lval);
  62.   if(nextop(opstr)==0) return k;
  63.   if(k) rvalue(lval);
  64.   while(1) {
  65.     if(nextop(opstr)) {
  66.       bump(opsize);
  67.       opindex=opindex+opoff;
  68.       plnge2(op[opindex], op2[opindex], hier, lval, lval2);
  69.       }
  70.     else return 0;
  71.     }
  72.   }
  73.  
  74. /*
  75. ** unary plunge to lower level
  76. */
  77. plnge1(hier, lval) int (*hier)(), lval[]; {             /*13*/
  78.   char *before, *start;
  79.   int k;
  80.   setstage(&before, &start);
  81.   k=(*hier)(lval);                                      /*13*/
  82.   if(lval[3]) clearstage(before,0);  /* load constant later */
  83.   return k;
  84.   }
  85.  
  86. /*
  87. ** binary plunge to lower level
  88. */
  89. plnge2(oper, oper2, hier, lval, lval2)
  90.   int (*oper)(),(*oper2)(),(*hier)(),lval[],lval2[]; {  /*13*/
  91.   char *before, *start;
  92.   setstage(&before, &start);
  93.   lval[5]=1;          /* flag secondary register used */
  94.   lval[7]=0;          /* flag as not "... oper 0" syntax */
  95.   if(lval[3]) {       /* constant on left side not yet loaded */
  96.     if(plnge1(hier, lval2)) rvalue(lval2);
  97.     if(lval[4]==0) lval[7]=stagenext;
  98.     const2(lval[4]<<dbltest(oper, lval2, lval)); /*34*/
  99.     }
  100.   else {              /* non-constant on left side */
  101.     push();
  102.     if(plnge1(hier, lval2)) rvalue(lval2);
  103.     if(lval2[3]) {    /* constant on right side */
  104.       if(lval2[4]==0) lval[7]=start;
  105.       if(oper==ffadd) { /* may test other commutative operators */
  106.         csp=csp+2;
  107.         clearstage(before, 0);
  108.         const2(lval2[4]<<dbltest(oper, lval, lval2)); /*34*/
  109.                                     /* load secondary */
  110.         }
  111.       else {
  112.         const(lval2[4]<<dbltest(oper, lval, lval2)); /*34*/
  113.                                     /* load primary */
  114.         smartpop(lval2, start);
  115.         }
  116.       }
  117.     else {            /* non-constants on both sides */
  118.       smartpop(lval2, start);
  119.                                                  /*34*/
  120.       if(dbltest(oper, lval,lval2)) doublereg(); /*34*/
  121.       if(dbltest(oper, lval2,lval)) {            /*34*/
  122.         swap();
  123.         doublereg();
  124.         if(oper==ffsub) swap();
  125.         }
  126.                                                  /*34*/
  127.       }
  128.     }
  129.   if(oper) {
  130.     if(lval[3]=lval[3]&lval2[3]) {
  131.       lval[4]=calc(lval[4], oper, lval2[4]);
  132.       clearstage(before, 0);  
  133.       lval[5]=0;
  134.       }
  135.     else {
  136.       if((lval[2]==0)&(lval2[2]==0)) {
  137.         (*oper)();                                      /*13*/
  138.         lval[6]=oper;    /* identify the operator */
  139.         }
  140.       else {
  141.         (*oper2)();                                     /*13*/
  142.         lval[6]=oper2;   /* identify the operator */
  143.         }
  144.       }
  145.     if(oper==ffsub) {
  146.       if((lval[2]==CINT)&(lval2[2]==CINT)) {
  147.         swap();
  148.         const(1);
  149.         ffasr();  /** div by 2 **/
  150.         }
  151.       }
  152.     if((oper==ffsub)|(oper==ffadd)) result(lval, lval2);
  153.     }
  154.   }
  155.  
  156. calc(left, oper, right) int left, (*oper)(), right; {   /*13*/
  157.        if(oper ==  ffor) return (left  |  right);
  158.   else if(oper == ffxor) return (left  ^  right);
  159.   else if(oper == ffand) return (left  &  right);
  160.   else if(oper ==  ffeq) return (left  == right);
  161.   else if(oper ==  ffne) return (left  != right);
  162.   else if(oper ==  ffle) return (left  <= right);
  163.   else if(oper ==  ffge) return (left  >= right);
  164.   else if(oper ==  fflt) return (left  <  right);
  165.   else if(oper ==  ffgt) return (left  >  right);
  166.   else if(oper == ffasr) return (left  >> right);
  167.   else if(oper == ffasl) return (left  << right);
  168.   else if(oper == ffadd) return (left  +  right);
  169.   else if(oper == ffsub) return (left  -  right);
  170.   else if(oper ==ffmult) return (left  *  right);
  171.   else if(oper == ffdiv) return (left  /  right);
  172.   else if(oper == ffmod) return (left  %  right);
  173.   else return 0;
  174.   }
  175.  
  176. expression(const, val) int *const, *val;  {
  177.   int lval[8];
  178.   explevel = 0;
  179.   if(hier1(lval)) rvalue(lval);
  180.   if(lval[3]) {
  181.     *const=1;
  182.     *val=lval[4];
  183.     }
  184.   else *const=0;
  185.   }
  186.  
  187. hier1(lval)  int lval[];  {
  188.   int k,lval2[8], lval3[2], oper, ducon1, ducon2;    /* fas 2.2 */
  189.   k=plnge1(hier3, lval);
  190.   if(match("?")) ducond();                /* fas 2.2 */
  191.  
  192.   if(lval[3]) const(lval[4]);
  193.        if(match("|="))  oper=ffor;
  194.   else if(match("^="))  oper=ffxor;
  195.   else if(match("&="))  oper=ffand;
  196.   else if(match("+="))  oper=ffadd;
  197.   else if(match("-="))  oper=ffsub;
  198.   else if(match("*="))  oper=ffmult;
  199.   else if(match("/="))  oper=ffdiv;
  200.   else if(match("%="))  oper=ffmod;
  201.   else if(match(">>=")) oper=ffasr;
  202.   else if(match("<<=")) oper=ffasl;
  203.   else if(match("="))   oper=0;
  204.   else return k;
  205.   if(k==0) {
  206.     needlval();
  207.     return 0;
  208.     }
  209.   lval3[0] = lval[0];
  210.   lval3[1] = lval[1];
  211.   if(lval[1]) {
  212.     if(oper) {
  213.       push();
  214.       rvalue(lval);
  215.       }
  216.     plnge2(oper, oper, hier1, lval, lval2);
  217.     if(oper) pop();
  218.     }
  219.   else {
  220.     if(oper) {
  221.       rvalue(lval);
  222.       plnge2(oper, oper, hier1, lval, lval2);
  223.       }
  224.     else {
  225.       if(hier1(lval2)) rvalue(lval2);
  226.       lval[5]=lval2[5];
  227.       }
  228.     }
  229.   if(match("?")) {                    /* fas 2.2 */
  230.     ducon1 = lval[1];
  231.     ducon2 = lval;
  232.     ducond();
  233.     lval[1] = ducon1;
  234.     lval = ducon2;
  235.   }
  236.  
  237.   store(lval3);
  238.   return 0;
  239.   }
  240.  
  241. ducond() {                        /* fas 2.2 */
  242.   int flab1, flab2, const, val;
  243.  
  244.   flab1 = getlabel();    /* label for false branch */
  245.   flab2 = getlabel();    /* label for true exit    */
  246.   testjump(flab1);
  247.   expression(&const,&val);
  248.   jump(flab2);
  249.   postlabel(flab1);
  250.   if(amatch(":",1) ==0) error("colon expected");
  251.   expression(&const,&val);
  252.   postlabel(flab2);
  253. }
  254.  
  255. hier3(lval)  int lval[]; {
  256.   return skim("||", eq0, 1, 0, hier4, lval);
  257.   }
  258.  
  259. hier4(lval)  int lval[]; {
  260.   return skim("&&", ne0, 0, 1, hier5, lval);
  261.   }
  262.  
  263. hier5(lval)  int lval[]; {
  264.   return plnge("|", 0, hier6, lval);
  265.   }
  266.  
  267. hier6(lval)  int lval[]; {
  268.   return plnge("^", 1, hier7, lval);
  269.   }
  270.  
  271. hier7(lval)  int lval[]; {
  272.   return plnge("&", 2, hier8, lval);
  273.   }
  274.  
  275. hier8(lval)  int lval[];  {
  276.   return plnge("== !=", 3, hier9, lval);
  277.   }
  278.  
  279. hier9(lval)  int lval[];  {
  280.   return plnge("<= >= < >", 5, hier10, lval);
  281.   }
  282.  
  283. hier10(lval)  int lval[];  {
  284.   return plnge(">> <<", 9, hier11, lval);
  285.   }
  286.  
  287. hier11(lval)  int lval[];  {
  288.   return plnge("+ -", 11, hier12, lval);
  289.   }
  290.  
  291. hier12(lval)  int lval[];  {
  292.   level = 0;
  293.   return plnge("* / %", 13, hier13, lval);
  294.   }
  295.  
  296.